package com.tech.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.tech.model.*;
import com.tech.repo.CommonRepo;
import com.tech.repo.LogEntityRepository;
import com.tech.service.Processor;
import com.tech.repo.GlobalConfigEntityRepository;
import com.tech.repo.TemplateEntityRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * Created by zouyao on 2023/06/06
 */
@RestController("api")
@RequiredArgsConstructor
@Slf4j
public class ApiController {

    private final TemplateEntityRepository     templateRepo;
    private final GlobalConfigEntityRepository globalConfigRepo;
    private final LogEntityRepository          logRepo;
    private final CommonRepo                   commonRepo;
    private final Processor                    processor;

    @GetMapping(value = "template/list")
    public List<TemplateEntity> templateList(){
        return templateRepo.findAll();
    }

    @PostMapping (value = "template/add")
    public void templateAdd(@RequestBody TemplateEntity entity){
        templateRepo.saveAndFlush(entity);
    }

    @PostMapping (value = "template/update")
    @Transactional(rollbackFor = Exception.class)
    public void templateUpdate(@RequestBody TemplateEntity entity){
        templateRepo.deleteById(entity.getId());
        templateRepo.saveAndFlush(entity);
    }

    @GetMapping (value = "template/delete")
    public void templateDelete(@RequestParam Long id){
        templateRepo.deleteById(id);
    }

    @GetMapping(value = "globalConfig/list")
    public List<GlobalConfigEntity> globalConfigList(){
        return globalConfigRepo.findAll();
    }

    @GetMapping(value = "globalConfig/add")
    public void globalConfigAdd(@RequestBody GlobalConfigEntity entity){
        globalConfigRepo.saveAndFlush(entity);
    }

    @GetMapping(value = "globalConfig/update")
    @Transactional(rollbackFor = Exception.class)
    public void globalConfigUpdate(@RequestBody GlobalConfigEntity entity){
        globalConfigRepo.deleteById(entity.getId());
        globalConfigRepo.saveAndFlush(entity);
    }

    @GetMapping (value = "globalConfig/delete")
    public void globalConfigDelete(@RequestParam Long id){
        globalConfigRepo.deleteById(id);
    }

    @PostMapping (value = "generator")
    public List<GeneratorResult> generator(@RequestParam("file") MultipartFile file,@RequestParam("templateList") List<Long> templateList) throws IOException {

        File f= File.createTempFile(UUID.randomUUID().toString(), "." + file.getOriginalFilename());
        file.transferTo(f);

        List<TemplateEntity> selectedTemplateList = templateRepo.findAllById(templateList);
        Assert.notEmpty(selectedTemplateList);
        List<GeneratorResult> processResult = processor.process(f,selectedTemplateList);

        if (StrUtil.isNotBlank(commonRepo.getConfigByKey("log"))){
            new Thread( () -> {
                logRepo.saveAndFlush(
                        new LogEntity(
                                file.getOriginalFilename() + JSONUtil.toJsonStr(templateList),
                                JSONUtil.toJsonStr(processResult)
                        )
                );
            }).start();
        }

        FileUtil.del(f);
        return processResult;
    }

}
